﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Infra_common
{
    public class PictureManger
    {
        /// <summary>
        /// 如果成功返回一个list<string>，没有成功返回null
        /// </summary>
        /// <param name="files">IFormFileCollection</param>
        /// <param name="uid">uid</param>
        /// <param name="cid">cid</param>
        /// <returns></returns>
        public async Task<List<string>> AddPicture(IFormFileCollection files, string uid, string cid)
        {
            List<string> filepath = new List<string>();
            //先判断是否存在文件夹
            if (!Directory.Exists(Path.Combine("wwwroot\\CommodityImg", uid)))
            {
                Directory.CreateDirectory(Path.Combine("wwwroot\\CommodityImg", uid));
                if (!Directory.Exists(Path.Combine("wwwroot\\CommodityImg", uid, cid)))
                {
                    Directory.CreateDirectory(Path.Combine("wwwroot\\CommodityImg", uid, cid));
                }
            }
            //文件校验
            foreach (var file in files)
            {
                

                var filename = Path.GetRandomFileName();
                //构建文件目录  根目录 子目录 文件名  扩展名
                var filePath = Path.Combine("wwwroot\\CommodityImg", uid, cid, filename);

                var stream = await ProcessFormFile(file, new string[]{".png"
                }, 1024*500);
                
                if (!File.Exists(filePath))
                {
                    using (var target = System.IO.File.Create(filePath))
                    {
                        await target.WriteAsync(stream, 0, stream.Length);
                    }
                }
  
                
                filepath.Add(filePath);
            }
            return filepath;
        }
        public bool DeletePicture(string uid, string cid, string filename)
        {
            var filePath = Path.Combine("wwwroot\\", "CommodityImg\\", uid, cid, filename);
            DirectoryInfo subdir = new DirectoryInfo(filePath);
            try
            {
                subdir.Delete(true);
                return true;
            }
            catch
            {
                return false;
            }

        }

        public async Task<List<string>> UpdatePicture(IFormFileCollection files, string uid, string cid, string filename)
        {
            if (DeletePicture(uid, cid, filename))
            {
                var filepath = await AddPicture(files, uid, cid);
                return filepath;
            }
            else
            {
                return null;
            }
        }
        public readonly long FormFileSizeLimit;
        private static async Task<byte[]> ProcessFormFile(IFormFile formFile, string[] permittedExtensions, long sizeLimit)
        {
            if (formFile.Length > sizeLimit || formFile.Length == 0)
            {
                return new byte[0];
            }

            try
            {
                using (var memoryStream = new MemoryStream())
                {
                    await formFile.CopyToAsync(memoryStream);

                    if (memoryStream.Length == 0)
                    {
                        return new byte[0];
                    }
                    if (!IsValidFileExtensionAndSignature(formFile.FileName, memoryStream, permittedExtensions))
                    {
                        return new byte[0];
                    }
                    else
                    {
                        return memoryStream.ToArray();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private static bool IsValidFileExtensionAndSignature(string fileName, Stream data, string[] permittedExtensions)
        {
            //检查为空
            if (string.IsNullOrEmpty(fileName) || data == null || data.Length == 0)
            {
                return false;
            }

            //获取扩展名
            var ext = Path.GetExtension(fileName).ToLowerInvariant();

            //检查扩展名是否被允许或者为空
            if (string.IsNullOrEmpty(ext) || !permittedExtensions.Contains(ext))
            {
                return false;
            }

            //using (var reader = new BinaryReader(data))
            //{
            //    //可以在此做字符检验，检查文本文件种是否含有特定字符

            //    //下面为文件签名校验
            //    var signatures = _fileSignature[ext];
            //    var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));

            //    return signatures.Any(signature =>
            //        headerBytes.Take(signature.Length).SequenceEqual(signature));
            //}
            return true;
        }

        private static readonly Dictionary<string, List<byte[]>> _fileSignature = new Dictionary<string, List<byte[]>>
        {
            {".gif", new List<byte[]> {new byte[] {0x47, 0x49, 0x46, 0x38}}},
            {".png", new List<byte[]> {new byte[] {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}}},
            {
                ".jpeg", new List<byte[]>
                {
                    new byte[] {0xFF, 0xD8, 0xFF, 0xE0},
                    new byte[] {0xFF, 0xD8, 0xFF, 0xE2},
                    new byte[] {0xFF, 0xD8, 0xFF, 0xE3},
                }
            },
            {
                ".jpg", new List<byte[]>
                {
                    new byte[] {0xFF, 0xD8, 0xFF, 0xE0},
                    new byte[] {0xFF, 0xD8, 0xFF, 0xE1},
                    new byte[] {0xFF, 0xD8, 0xFF, 0xE8},
                }
            },
            {
                ".zip", new List<byte[]>
                {
                    new byte[] {0x50, 0x4B, 0x03, 0x04},
                    new byte[] {0x50, 0x4B, 0x4C, 0x49, 0x54, 0x45},
                    new byte[] {0x50, 0x4B, 0x53, 0x70, 0x58},
                    new byte[] {0x50, 0x4B, 0x05, 0x06},
                    new byte[] {0x50, 0x4B, 0x07, 0x08},
                    new byte[] {0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70},
                }
            },
        };
    }
}
